/*******************************************************************************
 * Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 * Copyright (c) 2011- kotemaru@kotemaru.org
 ******************************************************************************/
package org.kotemaru.gae.dstool.client;

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.*;
import org.kotemaru.util.json.*;
import org.kotemaru.util.*;
import org.kotemaru.gae.dstool.DsToolConst;

/**
 */
public class EntityDownloader implements DsToolConst {

	private Writer writer;
	private String baseUrl;
	private int limit = 100;
	private HttpURLConnection conn;
	private GaeOAuthClient client;

	public EntityDownloader(GaeOAuthClient client, Writer writer, String url, String kind) {
		this.client = client;
		this.writer = writer;
		this.baseUrl = url + "?kind="+kind;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}


	public void download() throws Exception   {
		String offset = download(null, limit);
		while (offset != null) {
			offset = download(offset, limit);
		}
		writer.flush();
	}
	private String download(String offset, int limit) throws Exception {
		String loc = baseUrl +"&limit="+limit;
		if (offset != null) {
			loc += "&offset="+URLEncoder.encode(offset,UTF8);
		}

		open(loc);
		try {
			int status = conn.getResponseCode();
			System.err.println("Status: "+status);
			if (status == 200) return writeData();
			if (status == 204) return null; // 終了
			return null; // error.
		} finally {
			close();
		}
	}
	private String writeData() throws Exception {
		Map lastKey = null;

		InputStream in =  conn.getInputStream();
		BufferedReader r =
				new BufferedReader(new InputStreamReader(in, "UTF-8"));
		JSONParser parser = new JSONParser();

		int count = 0;
		String line = r.readLine();
		while (line != null) {
//System.err.println(line);
			try {
				Map map = parser.parse(line);
				lastKey = (Map) map.get("__key__");
			} catch (Exception e) {
				// ignore
				System.err.println("Skip broken data: "+e);
			}
			writer.write(line);
			writer.write("\n");
			line = r.readLine();
			count++;
		}
		System.err.println("Download "+count+" entities.");
		
		
		JSONSerializer seri = new JSONSerializer();
		return seri.getString(lastKey, "utf-8");
	}

	private void open(String loc)  throws Exception {
//loc += "&application_name=test-kotemaru";

		System.err.println("Request "+loc);
		conn = (HttpURLConnection) new URL(loc).openConnection();
		conn.setFollowRedirects(true); 
		conn.setRequestMethod("GET");

		String oauth = client.getOAuthHeader("GET", loc);
System.out.println("===>"+oauth);
		conn.setRequestProperty("Authorization", oauth);
		conn.setRequestProperty("Connection", "close");
		conn.setRequestProperty("Accept", "");

		conn.setDoOutput(false);
		conn.connect();
	}

	public void close()  throws Exception {
		if (conn == null) return;

		int count = 0;
		int status = conn.getResponseCode();
		//System.err.println("Status: "+status);
		if (status > 400) {
			System.err.println(IOUtil.streamToString(conn.getErrorStream(),"UTF-8"));
		}
		conn.disconnect();
		conn = null;
	}

}